package cn.wolfcode.web.controller;

import cn.wolfcode.common.constants.CommonConstants;
import cn.wolfcode.common.domain.UserInfo;
import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.CommonCodeMsg;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.common.web.anno.RequireLogin;
import cn.wolfcode.mq.MQConstant;
import cn.wolfcode.mq.OrderMessage;
import cn.wolfcode.redis.CommonRedisKey;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.IOrderInfoService;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.ConcurrentHashMap;


@RestController
@RequestMapping("/order")
@Slf4j
public class OrderInfoController {
    @Autowired
    private ISeckillProductService seckillProductService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private IOrderInfoService orderInfoService;
    
    public static final ConcurrentHashMap<Long,Boolean>LOCAL_FLAG_MAP=new ConcurrentHashMap<>();

    
    
    @RequireLogin
    @PostMapping("/doSeckill")
    public Result doSeckill(@RequestParam("time") Integer time,
                            @RequestParam("seckillId") Long seckillId,
                            @RequestHeader(CommonConstants.TOKEN_NAME) String token
    ){
        //1)判断本地标识,如果本地标识为true表示放行,如果为false,表示秒杀结束.
        Boolean flag = LOCAL_FLAG_MAP.get(seckillId);
        if (flag==null){
            LOCAL_FLAG_MAP.put(seckillId,true);
        }else if (flag==false){
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }
        //        3)判断是否是重复下单,如果重复下单,抛异常返回.
        String orderSetRealKey = SeckillRedisKey.SECKILL_ORDER_SET.getRealKey(String.valueOf(seckillId));
        String strObj = redisTemplate.opsForValue().get(CommonRedisKey.USER_TOKEN.getRealKey(token));
        Long phone = JSON.parseObject(strObj, UserInfo.class).getPhone();
        Boolean member = redisTemplate.opsForSet().isMember(orderSetRealKey, String.valueOf(phone));
        if (member&&member!=null){
            throw new BusinessException(SeckillCodeMsg.REPEAT_SECKILL);
        }
//        2)如果为true,判断redis中是否有库存.库存-1
        String bigkeystory = CommonRedisKey.SECKILL_PRODUCT_STORE.getRealKey(String.valueOf(time));
        Long storeCount = redisTemplate.opsForHash().increment(bigkeystory, String.valueOf(seckillId), -1);
        if (storeCount<0){
//如果没有, 修改本地标识为false, 秒杀结束
            LOCAL_FLAG_MAP.put(seckillId,false);
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }


//        4)发动Mq消息.携带数据(token)
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setSeckillId(seckillId);
        orderMessage.setTime(time);
        orderMessage.setToken(token);
        orderMessage.setUserPhone(phone);
        rocketMQTemplate.syncSend(MQConstant.ORDER_PEDDING_TOPIC,orderMessage);
//        5)返回给前端一个Result数据,告诉秒杀完成,等待结果.
        return Result.success("请等待结果");
    }
    
    @RequireLogin
    @GetMapping("/find")
    public Result find(String orderNo){
        if (StringUtils.isEmpty(orderNo)){
            throw new BusinessException(CommonCodeMsg.NO_PARAM_ERROR);
        }
            return Result.success(orderInfoService.findOrderByOrderNo(orderNo));
    }
    

    
}
